package com.dd.common.base

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding
import java.lang.reflect.ParameterizedType

abstract class BaseFragment<B : ViewBinding, V : BaseViewModelAbs<*>> : Fragment() {
    protected var binding: B? = null
    protected var model: V? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = setLayout(inflater, container)
        initUI()
        return view
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding = null
    }

    private fun setLayout(inflater: LayoutInflater, container: ViewGroup?): View? {
        var view: View? = null
        val viewBindingClass: Class<B>
        val viewModelClass: Class<V>
        try {
            val type = javaClass.genericSuperclass ?: return null
            val types = (type as ParameterizedType).actualTypeArguments
            if (types.size < 2) {
                Log.e("BaseFragment", "泛型不完整")
                return null
            }
            viewBindingClass = types[0] as Class<B>
            viewModelClass = types[1] as Class<V>
            val method = viewBindingClass.getMethod(
                "inflate", *arrayOf(
                    LayoutInflater::class.java,
                    ViewGroup::class.java,
                    Boolean::class.javaPrimitiveType
                )
            )
            binding = method.invoke(
                viewBindingClass, *arrayOf(inflater, container, java.lang.Boolean.FALSE)
            ) as B
            model = ViewModelProvider(this)[viewModelClass]

            model?.let {
                it.setContext(requireContext())
                it.getIsShowProgress().observe(viewLifecycleOwner) { isShow ->
                    if (isShow) {
                        showProgress()
                    } else {
                        hideProgress()
                    }
                }
                it.getNoticeMessage().observe(viewLifecycleOwner) { noticeMessage ->
                    showNotice(
                        noticeMessage.type,
                        noticeMessage.message
                    )
                }
            }
            initObserver()
        } catch (e: Exception) {
            e.printStackTrace()
            return null
        }
        view = binding?.root
        return view
    }

    fun showProgress() {

    }

    fun hideProgress() {

    }

    fun showNotice(type: Int, notice: String) {

    }
    protected abstract fun initUI()
    protected abstract fun initObserver()
}